<template>
  <v-container fluid>
    <v-row justify="start">
      <v-col
        cols="12"
        md="10"
      >
        <v-alert
          :type="alertType"
          dense
          icon="mdi-monitor-dashboard"
        >
          <v-row
            class="mt-1"
            dense
          >
            {{ lanChar.status.CommandLineInput }}
            <v-btn
              class="mt-n1"
              fab
              icon
              x-small
              color="primary"
              @click="wsReconn"
            >
              <v-icon>mdi-cached</v-icon>
            </v-btn>
            <v-spacer />
            <v-select
              v-model="svc"
              class="mt-n1"
              style="width: 10px"
              outlined
              dense
              hide-details
              :items="filter.svcs"
              :label="lanChar.status.SvcInstance"
              :hint="lanChar.status.SvcInstanceSelectHint"
            />
          </v-row>
        </v-alert>
        <v-text-field
          v-model.trim="commandText"
          color="purple"
          clearable
          :label="lanChar.status.CommandLineInput"
          @keydown.enter="getCommandOutput"
          @keydown.escape="commandText=''"
        >
          <template
            v-slot:append-outer
          >
            <v-btn
              class="mt-n2 ml-4 mr-4"
              fab
              small
              elevation="2"
              height="44"
              width="44"
              @click="getCommandOutput()"
            >
              <v-icon>mdi-google-play</v-icon>
            </v-btn>
          </template>
        </v-text-field>
        <v-textarea
          v-model="printText"
          clearable
          clear-icon="mdi-close-circle"
          color="orange orange-darken-4"
          background-color="amber lighten-4"
          rows="50"
          row-height="6"
          outlined
          auto-grow
          :label="lanChar.status.CommandLineOutput"
          dense
        />
      </v-col>
      <v-col
        cols="12"
        md="2"
      >
        <v-list
          shaped
          dense
        >
          <v-subheader>{{ lanChar.status.CommandHistory }}</v-subheader>
          <v-list-item-group
            v-model="selectedItem"
            color="primary"
          >
            <v-list-item
              v-for="(item, i) in history"
              :key="i"
            >
              <v-list-item-content
                @click="commandText = item"
                @dblclick="executeCommand(item)"
              >
                <v-list-item-title v-text="item" />
              </v-list-item-content>
            </v-list-item>
          </v-list-item-group>
        </v-list>
      </v-col>
    </v-row>
    <material-snackbar-tip
      v-model="snackbarDescp.snackbar"
      :type="snackbarDescp.snackbarType"
      :timeout="snackbarDescp.snackbarTimeout"
      v-bind="{
        bottom: true,
        right: true
      }"
      :text="snackbarDescp.snackbarContent"
    />
  </v-container>
</template>

<script>
  import * as wso from '@/util/ws'
  import globalDef from '@/util/globals'
  import lan from '@/util/lan-char'
  import { get } from 'vuex-pathify'
  export default {
    name: 'CmdLine',
    data: () => ({
      snackbarDescp: {
        snackbar: false,
        snackbarContent: 'snackbar content',
        snackbarTimeout: 2000,
        snackbarType: 'info',
      },
      lanChar: lan.GetLan(),
      alertType: 'success',
      printText: '',
      commandText: '',
      selectedItem: 1,
      history: ['help'],
      ws: null,
      svc: '',
      svcs: {},
      filter: {
        svcs: [],
      },
      cmdLineSerialNum: 0,
      svcGetAllSerialNum: 0,
      svcUpdateSubReqSerialNum: 0,
    }),
    computed: {
      ...get('user', [
        'token',
      ]),
    },
    created () {
      globalDef.VueObject.$on('lanChange', lanChar => {
        this.lanChar = lanChar
      })

      var loc = (window.location + '').split('/')
      const url = 'ws://' + loc[2] + `/svclog/v1/ws?token=${this.token}`
      this.ws = wso.wsConn(url, this.wsOnopen, this.wsMsgHandler, this.wsOnclose)
      console.log('this.ws=', this.ws)
    },
    mounted () {
    },
    beforeDestroy () {
      wso.wsClose(this.ws)
    },
    methods: {
      tipInfo (level, content, timeout) {
        this.snackbarDescp.snackbarType = level
        this.snackbarDescp.snackbarContent = content
        this.snackbarDescp.snackbarTimeout = timeout
        this.snackbarDescp.snackbar = true
      },
      getCommandOutput () {
        var command = this.commandText
        this.cmdLineSerialNum++
        const data = {
          msgHead: {
            instanceID: 'apptpl-web-ui-client',
            resOrReq: 'req',
            requestType: 'command-execute',
            serialNum: this.cmdLineSerialNum,
          },
          data: {
            instanceID: this.svc,
            cmdLine: command,
          },
        }
        wso.wsSend(this.ws, data)
      },
      getSvcAll () {
        this.svcGetAllSerialNum++
        const data = {
          msgHead: {
            instanceID: 'apptpl-web-ui-client',
            resOrReq: 'req',
            requestType: 'svc-get-all',
            serialNum: this.svcGetAllSerialNum,
          },
        }
        wso.wsSend(this.ws, data)
      },
      executeCommand (command) {
        this.commandText = command
        this.getCommandOutput()
      },
      svcUpdateSub () {
        this.svcUpdateSubReqSerialNum++
        const data = {
          msgHead: {
            instanceID: 'apptpl-web-ui-client',
            resOrReq: 'req',
            requestType: 'svc-update-sub',
            serialNum: this.svcUpdateSubReqSerialNum,
          },
        }
        wso.wsSend(this.ws, data)
      },
      svcUpdateUnSub () {
        this.svcUpdateSubReqSerialNum++
        const data = {
          msgHead: {
            instanceID: 'apptpl-web-ui-client',
            resOrReq: 'req',
            requestType: 'svc-update-unsub',
            serialNum: this.svcUpdateSubReqSerialNum,
          },
        }
        wso.wsSend(this.ws, data)
      },
      wsOnopen () {
        this.getSvcAll()
        this.svcUpdateSub()
      },
      wsOnclose () {
        this.svcUpdateUnSub()
      },
      wsReconn () {
        this.ws = wso.wsReconn(this.ws, this.wsOnopen, this.wsMsgHandler, this.wsOnclose)
      },
      wsMsgHandler (data) {
        var v = data && JSON.parse(data.data)
        // console.log('wsMsgHandler v: ', v)
        if (v.msgHead !== undefined && v.msgHead.resOrReq !== undefined) {
          switch (v.msgHead.resOrReq) {
            case 'req':
              this.wsReqHandler(v)
              break
            case 'res':
              this.wsResHandler(v)
              break
            default:
              break
          }
        }
      },
      wsReqHandler (v) {
        switch (v.msgHead.requestType) {
          case 'xxx':
            break

          case 'svc-update-pub':
            if (v.msgHead.status === 'ok') {
              v.data.svcUpdateInfo.forEach(e => {
                const index = this.filter.svcs.indexOf(e.instanceID)
                if (index === -1) {
                  if (e.action === 'on') {
                    this.filter.svcs.push(e.instanceID)
                  }
                } else {
                  if (e.action === 'off') {
                    this.filter.svcs.splice(index, 1)
                  }
                }
              })
            }
            break

          default:
            break
        }
      },
      wsResHandler (v) {
        switch (v.msgHead.requestType) {
          case 'command-execute':
            if (v.msgHead.status === 'ok' && v.msgHead.serialNum === this.cmdLineSerialNum) {
              this.printText = v.data.out
              const command = v.data.cmdLine
              if (this.history[0] !== command) {
                var index = this.history.indexOf(command)
                if (index !== -1) {
                  this.history.splice(index, 1)
                }
                this.history.unshift(command)
              }
            }
            break

          case 'svc-get-all':
            if (v.msgHead.status === 'ok' && v.msgHead.serialNum === this.svcGetAllSerialNum) {
              this.svcs = v.data
              this.filter.svcs = []
              for (const k in this.svcs) {
                this.filter.svcs.push(k)
              }
              if (this.filter.svcs.length >= 0) {
                this.svc = this.filter.svcs[0]
              }
            }
            break

          default:
            break
        }
      },
    },
  }

</script>
